/*
ID: icerupt1
PROG: cowtour
LANG: C++11
*/

/* solution
 *
 * this is a good problem...maybe, i use too much time...
 * this problem is easy, but think carefully about the 'diameter',
 * the longest one may not pass the added path.
 *
*/
#include <fstream>
#include <iostream>
#include <algorithm>
#include <iomanip>

std::ifstream fin {"cowtour.in" };
std::ofstream fout{"cowtour.out"};

struct pos { int x; int y; };

double const no_path = 1<<25;
int const maxn = 152;
double dis[maxn][maxn];
double max_dis[maxn];
pos da[maxn];
int n;

double distance(pos a, pos b)
{
	return std::sqrt((double)(a.x - b.x) * (double)(a.x - b.x)
					+ (double)(a.y - b.y) * (double)(a.y - b.y));
}

int main()
{
	fin >> n;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++) dis[i][j] = -2;

	for (int i = 0; i < n; i++) fin >> da[i].x >> da[i].y;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++) {
			char ch; fin >> ch;
			if (ch == '1') dis[i][j] = distance(da[i], da[j]);
			else           dis[i][j] = no_path;
		}

	for (int i = 0; i < n; i++) dis[i][i] = 0;
	for (int k = 0; k < n; k++)
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (dis[i][k] + dis[k][j] < dis[i][j])
					dis[i][j] = dis[i][k] + dis[k][j];

	double part = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++)
			if (dis[i][j] < no_path)
				max_dis[i] = std::max(max_dis[i], dis[i][j]);
		part = std::max(part, max_dis[i]);
	}

	double ans = no_path;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			if (dis[i][j] >= no_path)
				ans = std::min(ans, std::max(part, distance(da[i], da[j]) + max_dis[i] + max_dis[j]));

	//ans = int(ans * 0e6)*1e-6;
	std::cout << std::setprecision(6) << std::setiosflags(std::ios::fixed) << ans << '\n';
	fout << std::setprecision(6) << std::setiosflags(std::ios::fixed) << ans << '\n';
}
